package com.zkthink.ceres.promotion.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zkthink.base.R;
import com.zkthink.base.service.SuperServiceImpl;
import com.zkthink.ceres.promotion.dao.PromotionMapper;
import com.zkthink.ceres.promotion.dto.PromotionAdminDTO;
import com.zkthink.ceres.promotion.dto.PromotionDetailDTO;
import com.zkthink.ceres.promotion.entity.Promotion;
import com.zkthink.ceres.promotion.enums.PromotionPlanEnum;
import com.zkthink.ceres.promotion.enums.PromotionTypeEnum;
import com.zkthink.ceres.promotion.service.PromotionAdminService;
import com.zkthink.ceres.promotion.service.PromotionPlanService;
import com.zkthink.ceres.promotion.strategy.LadderDiscountStrategy;
import com.zkthink.ceres.promotion.strategy.PlusDiscountStrategy;
import com.zkthink.ceres.promotion.strategy.PromotionPlanStrategy;
import com.zkthink.ceres.promotion.vo.admin.PromotionAdminPageVO;
import com.zkthink.ceres.promotion.vo.admin.PromotionAdminVO;
import com.zkthink.dozer.DozerUtils;
import com.zkthink.exception.BizException;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * <p>
 * 业务实现类
 * 营销活动后台接口
 * </p>
 *
 * @author kellen
 * @date 2020-06-16
 */
@Slf4j
@Service
@AllArgsConstructor
public class PromotionPlanServiceImpl extends SuperServiceImpl<PromotionMapper, Promotion> implements PromotionPlanService {

	private PromotionAdminService promotionAdminService;

	@Override
	public Long calculatePromotionPlanAmount(Long orderTotalAmount, Long promotionId, Optional<List<PromotionDetailDTO>> promotionDetailDTOList) {

		Promotion promotion = getPromotionById(promotionId);

		PromotionTypeEnum promotionTypeEnum = PromotionTypeEnum.getType(promotion.getPromotionType());
		PromotionPlanEnum promotionPlanEnum = PromotionPlanEnum.getPlan(promotion.getPromotionPlan());

		return getPromotionPlanStrategy(promotionPlanEnum).calculateAmount(orderTotalAmount, getPromotionDetailList(promotionTypeEnum, promotion, promotionDetailDTOList));
	}

	private List<PromotionDetailDTO> getPromotionDetailList(PromotionTypeEnum promotionTypeEnum,
															Promotion promotion, Optional<List<PromotionDetailDTO>> promotionDetailDTOList) {
		if (promotionTypeEnum.equals(PromotionTypeEnum.FULL_DISCOUNT)) {
			return convertToPromotionDetailList(promotion.getPromotionDetail());
		}
		return promotionDetailDTOList.orElse(Lists.newArrayList());
	}

	private List<PromotionDetailDTO> convertToPromotionDetailList(List<Map<String, Object>> promotionDetail) {
		String json = JSON.toJSONString(promotionDetail);
		return JSON.parseArray(json, PromotionDetailDTO.class);
	}

	private PromotionPlanStrategy getPromotionPlanStrategy(PromotionPlanEnum promotionPlanEnum) {
		switch (promotionPlanEnum) {
			case PLUS_DISCOUNT:
				return new PlusDiscountStrategy();
			case LADDER_DISCOUNT:
				return new LadderDiscountStrategy();
			default:
				return new PlusDiscountStrategy();
		}
	}

	private Promotion getPromotionById(Long promotionId) {
		return promotionAdminService.getById(promotionId);
	}
}
